home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 16
/
Aminet 16 (1996)(GTI - Schatztruhe)[!][Dec 1996].iso
/
Aminet
/
comm
/
term
/
term_source.lha
/
Extras
/
Source
/
term-source.lha
/
Hotkeys.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-10-20
|
7KB
|
396 lines
/*
** Hotkeys.c
**
** Hotkey support routines.
**
** Copyright © 1990-1996 by Olaf `Olsen' Barthel
** All Rights Reserved
**
** :ts=4
*/
#ifndef _GLOBAL_H
#include "Global.h"
#endif
enum { CX_TERMSCREENTOFRONT,CX_BUFFERSCREENTOFRONT,CX_SKIPDIALENTRY,CX_ABORTAREXX };
/* Asynchronous hotkey process. */
STATIC struct Process *CxProcess;
STATIC struct NewBroker TermBroker =
{
NB_VERSION,
"term",
"term © 1990-1996 by Olaf Barthel",
"Terminal program"
};
/* Hotkey(STRPTR Code,struct MsgPort *Port,LONG ID):
*
* A custom version of the amiga.lib supplied code.
*/
STATIC CxObj *
CustomHotKey(STRPTR Code,struct MsgPort *Port,LONG ID)
{
CxObj *Filter;
if(Filter = CxFilter(Code))
{
CxObj *Sender;
if(Sender = CxSender(Port,ID))
{
CxObj *Translator;
AttachCxObj(Filter,Sender);
if(Translator = CxTranslate(NULL))
{
AttachCxObj(Filter,Translator);
if(!CxObjError(Filter))
return(Filter);
}
}
DeleteCxObjAll(Filter);
}
return(NULL);
}
/* CreateBroker(struct MsgPort *CxPort):
*
* Set up a CxObj commodity broker.
*/
STATIC CxObj *
CreateBroker(struct MsgPort *CxPort)
{
CxObj *Broker;
/* Set the commodity priority. */
TermBroker.nb_Pri = Hotkeys.CommodityPriority;
/* Create the broker. */
if(Broker = CxBroker(&TermBroker,NULL))
{
/* Add the hotkeys. */
AttachCxObj(Broker,CustomHotKey(Hotkeys.termScreenToFront, CxPort,CX_TERMSCREENTOFRONT));
AttachCxObj(Broker,CustomHotKey(Hotkeys.BufferScreenToFront, CxPort,CX_BUFFERSCREENTOFRONT));
AttachCxObj(Broker,CustomHotKey(Hotkeys.SkipDialEntry, CxPort,CX_SKIPDIALENTRY));
AttachCxObj(Broker,CustomHotKey(Hotkeys.AbortARexx, CxPort,CX_ABORTAREXX));
/* Did an error show up? */
if(!CxObjError(Broker))
{
/* Broker has been added, now activate it. */
ActivateCxObj(Broker,Hotkeys.HotkeysEnabled);
return(Broker);
}
DeleteCxObjAll(Broker);
}
return(NULL);
}
/* TermCxServer():
*
* Asynchronous hotkey server.
*/
STATIC VOID SAVE_DS
TermCxServer(VOID)
{
struct MsgPort *CxPort;
CxMsg *Message;
CxObj *Broker;
/* Create a reply port. */
if(CxPort = CreateMsgPort())
{
/* Add the port to the public list. */
CxPort->mp_Node.ln_Name = TermBroker.nb_Name;
AddPort(CxPort);
/* Install the port. */
TermBroker.nb_Port = CxPort;
/* Create the broker. */
if(Broker = CreateBroker(CxPort))
{
ULONG SignalSet;
BOOL Terminated;
/* Signal father task that we're done. */
Signal((struct Task *)ThisProcess,SIG_HANDSHAKE);
/* Loop and loop... */
Terminated = FALSE;
while(!Terminated)
{
/* Wait for some signal. */
SignalSet = Wait(SIG_KILL | SIG_RESET | PORTMASK(CxPort));
/* ^C aborts. */
if(SignalSet & SIG_KILL)
Terminated = TRUE;
/* ^D removes the broker and
* creates a new one.
*/
if(SignalSet & SIG_RESET)
{
DeleteCxObjAll(Broker);
Broker = CreateBroker(CxPort);
}
/* A commodity message. */
if(SignalSet & PORTMASK(CxPort))
{
ULONG MessageType,MessageID;
/* Remove all messages. */
while(Message = (CxMsg *)GetMsg(CxPort))
{
/* Extract type and ID. */
MessageType = CxMsgID(Message);
MessageID = CxMsgType(Message);
ReplyMsg((struct Message *)Message);
/* Take a look at the type... */
switch(MessageID)
{
/* A hotkey was pressed. */
case CXM_IEVENT:
switch(MessageType)
{
case CX_TERMSCREENTOFRONT:
Forbid();
if(Window)
BumpWindow(TopWindow);
else
Signal((struct Task *)ThisProcess,SIGBREAKF_CTRL_F);
Permit();
break;
case CX_BUFFERSCREENTOFRONT:
LaunchBuffer();
break;
case CX_SKIPDIALENTRY:
Signal((struct Task *)ThisProcess,SIG_SKIP);
break;
case CX_ABORTAREXX:
if(InRexx)
Signal((struct Task *)ThisProcess,SIG_BREAK);
break;
}
break;
/* An internal commodity command. */
case CXM_COMMAND:
switch(MessageType)
{
case CXCMD_DISABLE:
ActivateCxObj(Broker,Hotkeys.HotkeysEnabled = FALSE);
break;
case CXCMD_ENABLE:
ActivateCxObj(Broker,Hotkeys.HotkeysEnabled = TRUE);
break;
}
break;
}
}
}
}
/* Remove the broker. */
DeleteCxObjAll(Broker);
}
/* Remove the port from the public list. */
RemPort(CxPort);
/* Remove all pendig messages. */
while(Message = (CxMsg *)GetMsg(CxPort))
ReplyMsg((struct Message *)Message);
/* Delete the reply port. */
DeleteMsgPort(CxPort);
}
Forbid();
/* Clear the task ID. */
CxProcess = NULL;
/* Signal father process that we're done. */
Signal((struct Task *)ThisProcess,SIG_HANDSHAKE);
}
/* ShutdownCx():
*
* Remove the hotkey task.
*/
VOID
ShutdownCx()
{
ShakeHands((struct Task *)CxProcess,SIG_KILL);
}
/* SetupCx():
*
* Create the hotkey task.
*/
BOOL
SetupCx()
{
/* If the task is already running, tell it to
* update the hotkey settings.
*/
if(CxProcess)
{
Signal((struct Task *)CxProcess,SIG_RESET);
return(TRUE);
}
else
{
if(CxProcess = StartProcessWaitForHandshake("term Hotkey Process",(TASKENTRY)TermCxServer,
NP_Priority, 0,
NP_WindowPtr, -1,
TAG_DONE))
return(TRUE);
}
return(FALSE);
}
/* LoadHotkeys(STRPTR Name,struct Hotkeys *Keys):
*
* Load the hotkey settings from a file.
*/
BOOL
LoadHotkeys(STRPTR Name,struct Hotkeys *Keys)
{
struct IFFHandle *Handle;
LONG Error;
if(!(Handle = OpenIFFStream(Name,MODE_OLDFILE)))
Error = IoErr();
else
{
/* Collect version number ID if
* available.
*/
if(!(Error = PropChunks(Handle,(LONG *)VersionProps,1)))
{
/* The following line tells iffparse to stop at the
* very beginning of a `Type' chunk contained in a
* `TERM' FORM chunk.
*/
if(!(Error = StopChunk(Handle,ID_TERM,ID_HOTK)))
{
/* Parse the file... */
if(!ParseIFF(Handle,IFFPARSE_SCAN))
{
struct StoredProperty *Prop;
/* Did we get a version ID? */
if(!(Prop = FindProp(Handle,ID_TERM,ID_VERS)))
Error = ERROR_OBJECT_WRONG_TYPE;
else
{
struct TermInfo *TermInfo;
TermInfo = (struct TermInfo *)Prop->sp_Data;
if((TermInfo->Version < CONFIG_FILE_VERSION) || (TermInfo->Version == CONFIG_FILE_VERSION && TermInfo->Revision < CONFIG_FILE_REVISION))
{
if(ReadChunkBytes(Handle,Keys,sizeof(struct HotkeysOld)) != sizeof(struct HotkeysOld))
Error = IoErr();
else
strcpy(Keys->AbortARexx,"lshift rshift escape");
}
else
{
if(ReadChunkBytes(Handle,Keys,sizeof(struct Hotkeys)) != sizeof(struct Hotkeys))
Error = IoErr();
}
}
}
}
}
CloseIFFStream(Handle);
}
if(Error)
{
SetIoErr(Error);
return(FALSE);
}
else
return(TRUE);
}